package route

import (
	"fmt"
	"io/ioutil"
	"more_ssh/conf"
	"more_ssh/middleware"
	"more_ssh/sql"
	"net/http"
	"os"
	"strconv"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
)

type ResultAudit struct {
	sql.Audit
	User     string `json:"user"`
	HostName string `json:"hostName"`
}

type WebMsg struct {
	Data []byte `json:"data"`
	// ReslutData string `json:"reslutData"`
}

func auditlist(c *gin.Context) {

	page, err := strconv.Atoi(c.DefaultQuery("page", "0"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"msg": "请求的参数有误，请检查 page 参数是否是整数",
		})
		return
	}
	pagesize, err := strconv.Atoi(c.DefaultQuery("pagesize", "10"))
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{
			"msg": "请求的参数有误，请检查 pagesize 参数是否是整数",
		})
		return
	}

	switch {
	case pagesize > 1000:
		pagesize = 1000
	case pagesize <= 10:
		pagesize = 10
	}

	// pagedb := sql.Paginate(page, pagesize)
	var audits []sql.Audit
	// conf.DB.Scopes(pagedb).Find(suer)
	conf.DB.Limit(pagesize).Offset(page * pagesize).Find(&audits)
	total := conf.DB.Find(&[]sql.Audit{}).RowsAffected
	var resultAudits []ResultAudit
	for _, audit := range audits {
		user := &sql.User{ID: audit.UserId}
		conf.DB.First(user)

		host := &sql.Host{ID: audit.HostId}
		conf.DB.First(host)

		audit.FilePath = ""
		resultAudits = append(resultAudits, ResultAudit{
			Audit:    audit,
			User:     user.Name,
			HostName: host.Name,
		})
	}

	c.JSON(http.StatusOK, gin.H{
		"page":     page,
		"pagesize": pagesize,
		"total":    total,
		"audits":   resultAudits,
	})
}

func replayerTui(c *gin.Context) {
	//校验token
	authorization, ok := c.GetQuery("Authorization")
	if !ok {
		fmt.Println("authorization获取失败")
		return
	}
	_, ok = middleware.WsParseToken(authorization)
	if !ok {
		fmt.Println("token解析失败")
		return
	}

	//获取前端传入的参数
	// id, ok := c.GetQuery("id")
	id := c.Param("id")
	idInt, err := strconv.Atoi(id)
	if err != nil {
		fmt.Println("传的参数不是整数")
		return
	}
	audit := &sql.Audit{ID: uint(idInt)}

	conf.DB.First(audit)
	if audit == nil {
		fmt.Println("没有这个会话id")
		return
	}
	// audit.FilePath
	//读取文件信息了

	//建立socket请求
	// 1. 升级请求websocket
	upGrader := websocket.Upgrader{
		ReadBufferSize:  1024,
		WriteBufferSize: 1024 * 1024 * 10,
		CheckOrigin: func(r *http.Request) bool {
			return true
		},
	}
	webcon, err := upGrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		fmt.Println("升级http 为websoket失败：", err)
	}
	defer webcon.Close()
	// webcon.WriteMessage(websocket.TextMessage, []byte("连接成功！"))
	//打开时间线文件 跟操作记录文件，时间线文件用来记录每次操作的字符个数
	tl, err := ioutil.ReadFile(audit.FilePath + ".tl")
	if err != nil {
		fmt.Println("读取时间线文件失败：", err)
		return
	}
	// string(tl)
	lines := strings.Split(string(tl), "\n")
	//解决index out问题
	lines = lines[:(len(lines) - 1)]

	//打开操作记录文件
	auditFile, err := os.Open(audit.FilePath + ".data")
	if err != nil {
		fmt.Println("读取操作记录文件文件失败：", err)
		return
	}
	fmt.Printf("lines个数： %d", len(lines))
	for _, line := range lines {
		lens := strings.Split(line, "\t")
		bufferSize, _ := strconv.Atoi(lens[1])
		buffer := make([]byte, bufferSize)
		_, err := auditFile.Read(buffer)
		if err != nil {
			fmt.Println("for 读取操作记录文件文件失败：", err)
			return
		}

		// webcon.WriteMessage(websocket.BinaryMessage, buffer)
		webcon.WriteJSON(&WebMsg{buffer})

		time.Sleep(100 * time.Millisecond)
	}

}
